//~ Project: TheGenerator File: GrailsTemplateGenerator.groovy Created date: Jul 28, 2011
package com.ii2d.tg

import grails.util.Metadata

import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.codehaus.groovy.grails.commons.GrailsClassUtils
import org.codehaus.groovy.grails.commons.GrailsDomainClass
import org.springframework.util.Assert

import com.ii2d.tg.generators.Generator
import com.ii2d.tg.generators.GeneratorFactory;

class TGGenerator {

	private final static Log LOG = LogFactory.getLog(TGGenerator.class)

	List<Generator> generators = new ArrayList<Generator>()
	GeneratorFactory generatorFactory 

	public TGGenerator() {
		generatorFactory = new GeneratorFactory()
	}

	public void generate(GrailsDomainClass domainClass, String destDir) {
		_init(domainClass, destDir)
		generators.each { 
			it.generate()
		}
	}

	private void _init(GrailsDomainClass domainClass, String destDir) {
		Assert.hasText destDir, "Argument [destDir] not specified"

		def settingsClosure = GrailsClassUtils.getStaticPropertyValue(domainClass.getClazz(), 'generatorSettings')
		if(settingsClosure instanceof Closure) {
			TGBuilder settingBuilder = new TGBuilder();
			settingsClosure.setDelegate(settingBuilder)
			settingsClosure.call()
			List<Node> settings = settingBuilder.getSettings()

			boolean foundProjectSetting = false
			settings.each {
				if(Metadata.current.getApplicationName() == it.name()) {
					generators = new ArrayList<Generator>()
					it.children().each { child -> _addGenerator(child, domainClass, destDir) }
					foundProjectSetting = true
				} else if(!foundProjectSetting) {
					_addGenerator(it, domainClass, destDir)
				}
			}
		}
	}

	private void _addGenerator(Node node, GrailsDomainClass domainClass, String destDir) {
		String name = node.name()
		Generator g = generatorFactory.newInstance(name, [
			node: node, 
			domainClass: domainClass, 
			destDir: destDir, 
			parentFactory: generatorFactory])
		if(g) this.generators.add(g)
	}
}